package com.framework.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.framework.core.exception.CustomException;
import com.framework.system.entity.SysDictItem;
import com.framework.system.entity.dto.SysDictItemAddDTO;
import com.framework.system.entity.dto.SysDictItemEditDTO;
import com.framework.system.entity.dto.SysDictItemQueryDTO;
import com.framework.system.entity.vo.SysDictItemListVO;
import com.framework.system.entity.vo.SysDictItemVO;
import com.framework.system.mapper.SysDictItemMapper;
import com.framework.system.service.ISysDictItemService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 字典项 服务实现类
 * </p>
 *
 * @author Kevin
 * @since 2021-06-10
 */
@Service
@AllArgsConstructor
public class SysDictItemServiceImpl implements ISysDictItemService {

    private SysDictItemMapper sysDictItemMapper;

    @Override
    public Page<SysDictItemListVO> selectPage(Page reqPage, SysDictItemQueryDTO req) {
        if (Objects.isNull(req.getDictId())) {
            Page<SysDictItemListVO> page = new Page<>();
            return page;
        }
        LambdaQueryWrapper<SysDictItem> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Objects.nonNull(req.getDictId()), SysDictItem::getDictId, req.getDictId());
        queryWrapper.like(StrUtil.isNotBlank(req.getDictItemCode()), SysDictItem::getDictItemCode, req.getDictItemCode());
        queryWrapper.like(StrUtil.isNotBlank(req.getDictItemName()), SysDictItem::getDictItemName, req.getDictItemName());
        queryWrapper.orderByAsc(SysDictItem::getSort);
        Page<SysDictItem> page = sysDictItemMapper.selectPage(reqPage, queryWrapper);
        Page<SysDictItemListVO> voPage = BeanUtil.copyProperties(page, Page.class);
        voPage.setRecords(BeanUtil.copyToList(page.getRecords(), SysDictItemListVO.class));
        return voPage;
    }

    @Override
    public List<SysDictItemListVO> selectList(SysDictItemQueryDTO req) {
        if (Objects.isNull(req.getDictId())) {
            return new ArrayList();
        }
        LambdaQueryWrapper<SysDictItem> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Objects.nonNull(req.getDictId()), SysDictItem::getDictId, req.getDictId());
        queryWrapper.like(StrUtil.isNotBlank(req.getDictItemCode()), SysDictItem::getDictItemCode, req.getDictItemCode());
        queryWrapper.like(StrUtil.isNotBlank(req.getDictItemName()), SysDictItem::getDictItemName, req.getDictItemName());
        queryWrapper.orderByAsc(SysDictItem::getSort);
        List<SysDictItem> list = sysDictItemMapper.selectList(queryWrapper);
        return BeanUtil.copyToList(list, SysDictItemListVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysDictItemAddDTO req) {
        if (!this.checkUniqueDictItemName(req.getDictItemName(), null, req.getDictId())) {
            throw new CustomException("字典项名称已存在");
        }
        if (!this.checkUniqueDictItemCode(req.getDictItemCode(), null, req.getDictId())) {
            throw new CustomException("字典项编码已存在");
        }
        SysDictItem entity = BeanUtil.copyProperties(req, SysDictItem.class);
        sysDictItemMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SysDictItemEditDTO req) {
        if (!this.checkUniqueDictItemName(req.getDictItemName(), req.getId(), req.getDictId())) {
            throw new CustomException("字典项名称已存在");
        }
        if (!this.checkUniqueDictItemCode(req.getDictItemCode(), req.getId(), req.getDictId())) {
            throw new CustomException("字典项编码已存在");
        }
        SysDictItem entity = BeanUtil.copyProperties(req, SysDictItem.class);
        sysDictItemMapper.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        idList.forEach(item -> {
            sysDictItemMapper.deleteById(item);
        });
    }

    @Override
    public SysDictItemVO view(String id) {
        SysDictItem entity = sysDictItemMapper.selectById(id);
        return BeanUtil.copyProperties(entity, SysDictItemVO.class);
    }

    private Boolean checkUniqueDictItemName(String value, Long id, Long dictId) {
        if (StrUtil.isBlank(value)) {
            return true;
        }
        id = Objects.isNull(id) ? -1L : id;
        SysDictItem entity = sysDictItemMapper.selectOne(Wrappers.lambdaQuery(SysDictItem.class)
                .eq(SysDictItem::getDictItemName, value)
                .eq(SysDictItem::getDictId, dictId));
        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
    }

    private Boolean checkUniqueDictItemCode(String value, Long id, Long dictId) {
        if (StrUtil.isBlank(value)) {
            return true;
        }
        id = Objects.isNull(id) ? -1L : id;
        SysDictItem entity = sysDictItemMapper.selectOne(Wrappers.lambdaQuery(SysDictItem.class)
                .eq(SysDictItem::getDictItemCode, value)
                .eq(SysDictItem::getDictId, dictId));
        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
    }

}
